package com.scs.application.modules.base.service.impl;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.scs.application.consts.GlobalConsts;
import com.scs.application.consts.SerialKeys;
import com.scs.application.core.exception.BusinessException;
import com.scs.application.core.service.BaseServiceImpl;
import com.scs.application.core.utils.DateUtils;
import com.scs.application.core.utils.StringUtils;
import com.scs.application.core.utils.UtilNum;
import com.scs.application.modules.base.entity.Change;
import com.scs.application.modules.base.entity.ChangeItem;
import com.scs.application.modules.base.entity.PackTempletItem;
import com.scs.application.modules.base.mapper.ChangeMapper;
import com.scs.application.modules.base.service.ChangeItemService;
import com.scs.application.modules.base.service.ChangeService;
import com.scs.application.modules.base.service.PackTempletItemService;
import com.scs.application.modules.base.service.PackTempletService;
import com.scs.application.modules.base.util.CommonService;
import com.scs.application.modules.sys.entity.Log;
import com.scs.application.modules.sys.enums.BusType;
import com.scs.application.modules.sys.enums.LogType;
import com.scs.application.modules.sys.mapper.LogMapper;
import com.scs.application.modules.wm.entity.Stock;
import com.scs.application.modules.wm.service.StockService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * <p>
 * 基础属性变更表 服务实现类
 * </p>
 */
@Service
public class ChangeServiceImpl extends BaseServiceImpl<ChangeMapper, Change> implements ChangeService {

    @Autowired
    private  PackTempletItemService packTempletItemService;

    @Autowired
    private PackTempletService packTempletService;

    @Autowired
    private ChangeItemService changeItemService;
    @Autowired
    private StockService stockService;

    @Autowired
    private LogMapper logMapper;

    @Override
    public boolean saveOrUpdate(Change entity) {
        if (StringUtils.isBlank(entity.getBusKey())) {
            entity.setBusKey(serialRuleAdapter.getSerialRuleService().generateCode(SerialKeys.BASE_CHANGE_KEY));
        }
        if (StringUtils.isBlank(entity.getBusKey())) {
            throw  new BusinessException("缺少系统编号规则【base_change_key】，请维护");
        }

        if (entity.getBusDate()  == null) {
            entity.setBusDate(DateUtils.now());
        }
        return super.saveOrUpdate(entity);
    }


    /**
    * @Description： 执行变更 状态置为end，然后执行相关操作
    */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public String execChange(Change entity) {
        if (entity.isNewRecord()){
            entity.setFlowStatus(GlobalConsts.FLOW_END_VALUE);
            this.saveOrUpdate(entity);
        }

        String msgTmp,msgType="";
        List<String> msgArr = new ArrayList<String>();
        switch (entity.getChangeType()){
            case GlobalConsts.ChangeType.matrSkuUnit: //耗材单位属性变更
                //更新耗材模板明细相关字段
                msgTmp = this.updatePackTempletItem(entity, Wrappers.<PackTempletItem>query()
                        .eq(entity.getChangeDataField(), entity.getChangeDataValue())
                        .eq(entity.getChangeProperty(), entity.getOldValue()));
                if (StringUtils.isNotBlank(msgTmp)) msgArr.add(msgTmp);

                //更新库存相关字段
                msgTmp = this.updateStock(entity);
                if (StringUtils.isNotBlank(msgTmp)) msgArr.add(msgTmp);
                break;

            case GlobalConsts.ChangeType.matrSkuQty: //耗材单品价格变更，因为会生成
                //更新耗材模板明细相关字段
                msgTmp = this.updatePackTempletItem(entity, Wrappers.<PackTempletItem>query()
                        .eq(entity.getChangeDataField(), entity.getChangeDataValue())
                        );
                if (StringUtils.isNotBlank(msgTmp)) msgArr.add(msgTmp);
                break;
            default:
                throw  new BusinessException("请手动实现");
        }
        msgArr.add(entity.getRemark());

        Log logInfo = Log.getLog(BusType.SPDType.type01, LogType.success, "系统", JSON.toJSONString(entity));
        logInfo.setMsg(entity.getChangeType());
        logMapper.insert(logInfo);
        CommonService.pushMessageRole(String.format("变更单：%s，%s",entity.getBusKey(),entity.getChangeType()), StringUtils.join(msgArr,","), "admin_yy,admin");
        return StringUtils.join(msgArr,",");
    }

    //更新耗材模板明细相关字段
    private String updatePackTempletItem(Change entity, QueryWrapper wrapper) {
        //耗材模板明细列表
        List<PackTempletItem> packTempletItems = packTempletItemService.list(wrapper);
        if (packTempletItems == null || packTempletItems.isEmpty()) return "";

        List<ChangeItem> changeItemSaveList = new ArrayList<ChangeItem>();
        ChangeItem changeItem;
        for(PackTempletItem packTempletItem : packTempletItems) {
            switch (entity.getChangeProperty()){
                case "sku_unit": //单品单位变更
                    //选择的是单品单位
                    if (packTempletItem.getSkuUnit().equals(packTempletItem.getPackageUnit()) ) {
                        packTempletItem.setPackageUnit(entity.getNewValue());
                    }
                    packTempletItem.setSkuUnit(entity.getNewValue());

                    changeItem = new ChangeItem();
                    changeItem.setAffectTable("base_pack_templet_item").setAffectTableText("耗材模板明细表").setAffectId(packTempletItem.getId()).setChangeId(entity.getId());
                    changeItemSaveList.add(changeItem);
                    break;
                case "sku_qty": //单品价格变更
                    //选择的是单品单位
                    if (packTempletItem.getSkuUnit().equals(packTempletItem.getPackageUnit()) ) {
                        packTempletItem.setPackageUnit(entity.getNewValue());
                    }
                    packTempletItem.setAmount(UtilNum.getDouble(entity.getNewValue())*packTempletItem.getSkuQty()).setSkuPrice(UtilNum.getDouble(entity.getNewValue()));

                    changeItem = new ChangeItem();
                    changeItem.setAffectTable("base_pack_templet_item").setAffectTableText("耗材模板明细表").setAffectId(packTempletItem.getId()).setChangeId(entity.getId());
                    changeItemSaveList.add(changeItem);
                    break;
                default:
                    throw  new BusinessException("请手动实现");
            }
        }

        //保存变更明细
        changeItemService.saveBatch(changeItemSaveList);

        //更新模板明细
        packTempletItemService.updateBatchById(packTempletItems);


        //单品价格变更后，修改主表汇总金额
        if (entity.getChangeProperty().equals("sku_qty")) {
            List<String> packTempletIds = packTempletItems.stream()
                    .map(PackTempletItem::getPackTempletId).distinct().collect(Collectors.toList());
            packTempletService.calculatePackAmount(packTempletIds);
        }
        return "影响耗材模板明细："+changeItemSaveList.size();
    }


    //更新库存相关字段
    private String updateStock(Change entity) {
        //耗材模板明细列表
        List<Stock> stockItems = stockService.list(
                Wrappers.<Stock>query()
                        .eq(entity.getChangeDataField(), entity.getChangeDataValue())
                        .eq(entity.getChangeProperty(), entity.getOldValue())
        );
        if (stockItems == null || stockItems.isEmpty()) return "";

        List<ChangeItem> changeItemSaveList = new ArrayList<ChangeItem>();
        ChangeItem changeItem;
        for(Stock stock : stockItems) {
            switch (entity.getChangeProperty()){
                case "sku_unit": //单品单位变更
                    //选择的是单品单位
                    if (stock.getSkuUnit().equals(stock.getPackageUnit()) ) {
                        stock.setPackageUnit(entity.getNewValue());
                    }
                    stock.setSkuUnit(entity.getNewValue());

                    changeItem = new ChangeItem();
                    changeItem.setAffectTable("wm_stock").setAffectTableText("库存表").setSn(stock.getSn()).setRfid(stock.getRfid())
                            .setAffectId(stock.getId()).setChangeId(entity.getId());
                    changeItemSaveList.add(changeItem);
                    break;
                default:
                    throw  new BusinessException("请手动实现");
            }
        }

        //保存变更明细
        changeItemService.saveBatch(changeItemSaveList);

        //更新库存明细
        stockService.updateBatchById(stockItems);

        return "影响库存："+changeItemSaveList.size();
    }
}
